home *** CD-ROM | disk | FTP | other *** search
- # -*- Fundamental -*-
- #
- # (C) 2002 Michel Arboi <arboi@alussinan.org>
- # $Revision: 1.49 $
-
- function replace_or_set_kb_item(name, value)
- {
- if (defined_func("replace_kb_item"))
- replace_kb_item(name: name, value: value);
- else
- set_kb_item(name: name, value: value);
- }
-
- function register_service(port, proto, ipproto)
- {
- local_var k;
- if (! ipproto) ipproto = "tcp";
- if (! service_is_unknown(port:port, ipproto: ipproto))
- {
- if (debug_level) display("service is already known on port ", ipproto, ":", port, "\n");
- #return(0);
- }
-
- k = strcat("Known/", ipproto, "/", port);
- set_kb_item(name: k, value: proto);
- if (ipproto == "tcp") k = strcat("Services/", proto);
- else k = strcat("Services/", ipproto, "/", proto);
- replace_or_set_kb_item(name: k, value: port);
- #display("register_service: port=", port, ", proto=", proto, "\n");
- }
-
- # This function may fork!
- function known_service(port, ipproto)
- {
- local_var k, p;
- if (! ipproto) ipproto = "tcp";
- k = strcat("Known/", ipproto, "/", port);
- p = get_kb_item(k);
- #if (p) { display("Known service on port ", port, "\n"); }
- #else { display("Unknown service on port ", port, "\n"); }
- return p;
- }
-
- # This function does not fork!
- function service_is_unknown(port, ipproto)
- {
- local_var k, p;
- if (! ipproto) ipproto = "tcp";
- k = strcat("Known/", ipproto, "/", port);
- p = get_kb_list(k);
- if (isnull(p)) return TRUE;
- foreach k (p)
- if (k != "unknown") # fool proof
- return FALSE;
- return TRUE;
- }
-
-
-
- function set_mysql_version(port, version)
- {
- local_var sb;
- sb = string("mysql/version/", port);
- set_kb_item(name: sb, value: version);
- }
-
- function get_mysql_version(port)
- {
- local_var sb, vers, soc, result, MySQL_version, end_found;
- sb = string("mysql/version/", port);
- vers = get_kb_item(sb);
- if (vers) return(vers);
- else { # Get it on the fly.
- if ( ! get_port_state(port) ) return NULL;
- soc = open_sock_tcp(port);
- if(!soc) return(NULL);
- result = recv(socket:soc, length:1000);
- close(soc);
- if(strlen(result) < 6)return(NULL);
- if("is not allowed" >< result)return(NULL);
- if("is blocked" >< result) return(NULL);
- MySQL_version = "";
- if ((result[1] == raw_string(0x00)) && (result[2] == raw_string(0x00)) &&
- (result[3] == raw_string(0x00)) && ((ord(result[4]) > 8) && (ord(result[4]) < 12))){
- end_found = FALSE;
- for (i = 0; end_found == FALSE ; i = i + 1) {
- if (result[5+i] == raw_string(0x00)) {
- end_found = TRUE;
- } else {
- MySQL_version = string(MySQL_version, result[5+i]);
- }
- }
- set_mysql_version(port:port, version:MySQL_version);
- return(MySQL_version);
- }
- }
- return(NULL);
- }
-
- function get_unknown_banner(port, ipproto, dontfetch)
- {
- local_var sb, banner, soc, req, tcp, p;
-
- if (! ipproto) ipproto = "tcp";
- tcp = ipproto == 'tcp';
- if (tcp)
- sb = strcat("unknown/banner/", port);
- else
- sb = strcat("unknown/banner/", ipproto, "/", port);
-
- banner = get_kb_item(sb);
- if (banner) return(banner);
-
- banner = get_kb_item("Banner/"+port);
- if (banner) return(banner);
-
- banner = get_kb_item("Amap/"+ipproto+"/"+port+"/FullBanner");
- if (banner) return(banner);
-
- foreach p (make_list("spontaneous", "get_http", "help"))
- {
- banner = get_kb_item("FindService/"+ipproto+"/"+port+"/"+p);
- if (banner) return(banner);
- }
-
- if (dontfetch) return(NULL);
- if (! get_port_state(port)) return (NULL);
- if (! tcp) return (NULL);
-
- soc = open_sock_tcp(port);
- if(!soc) return (NULL);
- # I don't think that it makes sense to send an HTTP request
- #req = http_head(item:"/", port:port);
- #send(socket:soc, data:req);
- banner = recv(socket:soc, length:2048);
- close(soc);
- if (banner)
- replace_or_set_kb_item(name: sb, value: banner);
- return(banner);
- }
-
- function set_unknown_banner(port, banner, ipproto)
- {
- local_var sb;
- if (! ipproto || ipproto == 'tcp')
- sb = string("unknown/banner/", port);
- else
- sb = strcat('unknown/banner/', ipproto, '/', port);
- set_kb_item(name: sb, value: banner);
- }
-
- #
- # Get the banner for a given service
- # You must also specify a default port, in case this is not in the kb
- #
- function get_service_banner_line(service, port, ipproto)
- {
- local_var banner, soc, key, gport, tcp;
- tcp = !ipproto || ipproto == 'tcp';
- if (tcp)
- gport = get_kb_item(strcat("Services/", service));
- else
- gport = get_kb_item(strcat("Services/", ipproto, "/", service));
- if(!gport) gport = port;
-
- if (tcp)
- key = strcat(service, "/banner/", gport);
- else
- key = strcat(service, "/banner/", ipproto, "/", gport);
-
- banner = get_kb_item(key);
-
- if(!banner)
- {
- if (! tcp) return;
-
- if(get_port_state(gport))
- {
- soc = open_sock_tcp(gport);
- if(soc)
- {
- banner = recv_line(socket:soc, length:2048);
- close(soc);
- }
- }
- # if (banner) set_kb_item(name: key, value: banner);
- }
-
- return(banner);
- }
- #
- # Fast replacement for getrpcport() which uses the libc
- #
- function get_rpc_port(program, protocol, portmap)
- {
- local_var broken, req, soc, r, port;
- local_var a, b, c, d, p_a, p_b, p_c, p_d, pt_a, pt_b, pt_c, pt_d;
-
-
-
- a = rand() % 255;
- b = rand() % 255;
- c = rand() % 255;
- d = rand() % 255;
-
- p_a = program / 16777216; p_a = p_a % 256;
- p_b = program / 65356; p_b = p_b % 256;
- p_c = program / 256; p_c = p_c % 256;
- p_d = program % 256;
-
- pt_a = protocol / 16777216; pt_a = pt_a % 256;
- pt_b = protocol / 65535 ; pt_b = pt_b % 256;
- pt_c = protocol / 256; ; pt_c = pt_c % 256;
- pt_d = protocol % 256;
-
-
- req = raw_string(a, b, c, d, # XID
- 0x00, 0x00, 0x00, 0x00, # Msg type: call
- 0x00, 0x00, 0x00, 0x02, # RPC Version
- 0x00, 0x01, 0x86, 0xA0, # Program
- 0x00, 0x00, 0x00, 0x02, # Program version
- 0x00, 0x00, 0x00, 0x03, # Procedure
- 0x00, 0x00, 0x00, 0x00, # Credentials - flavor
- 0x00, 0x00, 0x00, 0x00, # Credentials - length
- 0x00, 0x00, 0x00, 0x00, # Verifier - Flavor
- 0x00, 0x00, 0x00, 0x00, # Verifier - Length
-
- p_a, p_b, p_c, p_d, # Program
- 0xFF, 0xFF, 0xFF, 0xFF, # Version (any)
- pt_a, pt_b, pt_c, pt_d, # Proto (udp)
- 0x00, 0x00, 0x00, 0x00 # Port
- );
-
-
- if(isnull(portmap)){
- port = int(get_kb_item("rpc/portmap"));
- if(port == 0)port = 111;
- }
- else port = portmap;
-
-
- broken = get_kb_item(string("/tmp/rpc/noportmap/", port));
- if(broken)return(0);
-
-
- soc = open_sock_udp(port);
- send(socket:soc, data:req);
- r = recv(socket:soc, length:1024);
-
- close(soc);
- if(!r)
- {
- set_kb_item(name:string("/tmp/rpc/noportmap/", port), value:TRUE);
- return(0);
- }
-
- if(strlen(r) < 28)
- return(0);
- else
- {
- p_d = ord(r[27]);
- p_c = ord(r[26]);
- p_b = ord(r[25]);
- p_a = ord(r[24]);
- port = p_a;
- port = port * 256;
- port = port +p_b;
- port = port * 256;
- port = port + p_c;
- port = port * 256;
- port = port + p_d;
- return(port);
- }
- }
-
- #
- function rand_str(length, charset)
- {
- local_var l, i, s, n;
-
- if (! charset)
- charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
- if (isnull(length))
- length = 8;
- l = strlen(charset);
- s = "";
- for (i = 0; i < length; i ++)
- {
- n = rand() % l;
- s += charset[n];
- }
- return s;
- }
-
-
-
- function add_port_in_list(list, port)
- {
- local_var l;
-
-
- if(!get_port_state(port))
- {
- if(isnull(list))return make_list();
- else return list;
- }
-
- if(isnull(list))return make_list(port);
-
- foreach l (list)
- {
- if(l == port)
- return list;
- }
-
- return make_list(list, port);
- }
-
- # hex2raw was written by Renaud?
-
- function hex2raw(s)
- {
- local_var i, j, ret, l;
-
- s = chomp(s); # remove trailing blanks, CR, LF...
- l = strlen(s);
- if (l % 2) display("hex2raw: odd string: ", s, "\n");
- for(i=0;i<l;i+=2)
- {
- if(ord(s[i]) >= ord("0") && ord(s[i]) <= ord("9"))
- j = int(s[i]);
- else
- j = int((ord(s[i]) - ord("a")) + 10);
-
- j *= 16;
- if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9"))
- j += int(s[i+1]);
- else
- j += int((ord(s[i+1]) - ord("a")) + 10);
- ret += raw_string(j);
- }
- return ret;
- }
-
- function report_service(port, svc, banner)
- {
- local_var k, name, a;
-
- svc = tolower(svc);
- k = strcat(svc, "/banner/", port);
- set_kb_item(name: k, value: banner);
- register_service(port: port, proto: svc);
- if (svc == 'www') name = 'web server';
- else if (svc == 'proxy') name = 'web proxy';
- else if (svc == 'hylafax-ftp' || svc == 'hylafax') name = 'HylaFax server';
- else if (svc == 'agobot.fo') name = 'Agobot.fo backdoor';
- else if (svc == 'unknown_irc_bot') name = 'IRC bot';
- else name = toupper(svc) +' server';
- a = tolower(name[0]);
- if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'h') a = 'An ';
- else a = 'A ';
- security_note(port: port, data: a + name + ' is running on this port');
- }
-
-
-
-
-
- function base64_decode(str)
- {
- local_var len, i, j, k, ret, base64, b64;
- len = strlen(str);
- ret = "";
-
- base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- for (i = 0; i < 256; i++)
- b64[i] = 0;
- for (i = 0; i < strlen(base64); i++)
- b64[ord(base64[i])] = i;
-
- for(j=0;j<len;j+=4)
- {
- for (i = 0; i < 4; i++)
- {
- c = ord(str[j+i]);
- a[i] = c;
- b[i] = b64[c];
- }
-
- o[0] = (b[0] << 2) | (b[1] >> 4);
- o[1] = (b[1] << 4) | (b[2] >> 2);
- o[2] = (b[2] << 6) | b[3];
- if (a[2] == ord('='))
- i = 1;
- else if (a[3] == ord('='))
- i = 2;
- else
- i = 3;
- for(k=0;k<i;k++)
- ret += raw_string(int(o[k]) & 255);
-
- if (i < 3)
- break;
- }
-
- return ret;
- }
-
- __base64_code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- function base64_code(c)
- {
- return(__base64_code[c]);
- }
-
- function pow2(x)
- {
- __ret = 1;
- while(x)
- {
- __ret = __ret * 2;
- x = x - 1;
- }
- return(__ret);
- }
-
- function base64(str)
- {
- len = strlen(str);
- i = 0;
- ret = "";
- char_count = 0;
- _bits = 0;
- while(i < len)
- {
- _bits = _bits + ord(str[i]);
- char_count = char_count + 1;
- if(char_count == 3)
- {
- val = _bits / 262144;
- ret = string(ret, base64_code(c:val));
- val = _bits / 4096;
- val = val & 0x3F;
- ret = string(ret, base64_code(c:val));
- val = _bits / 64;
- val = val & 0x3F;
- ret = string(ret, base64_code(c:val));
- val = _bits & 0x3F;
- ret = string(ret, base64_code(c:val));
- char_count = 0;
- _bits = 0;
- }
- else {
- _bits = _bits * 256;
- }
- i = i + 1;
- }
-
-
- if(!(char_count == 0))
- {
- cnt = char_count * 8;
- mul = 16;
- mul = mul - cnt;
- mul = pow2(x:mul);
- _bits = _bits * mul;
- val = _bits / 262144;
- ret = string(ret, base64_code(c:val));
- val = _bits / 4096;
- val = val & 0x3F;
- ret = string(ret, base64_code(c:val));
- if(char_count == 1)
- {
- ret = string(ret, "==");
- }
- else
- {
- val = _bits / 64;
- val = val & 0x3F;
- ret = string(ret, base64_code(c:val), "=");
- }
- }
- return(ret);
- }
-
-
- # This function converts a string representing a decimal number to
- # to hexadecimal; eg, dec2hex(1098757090) == "417db3e2".
- #
- # Args:
- # o num, decimal number.
- #
- # Return:
- # hex number represented as a raw string.
- #
- # updated: 16-Nov-2004, George A. Theall
- #
- function dec2hex(num) {
- local_var digits, hex, rem;
- hex = "";
-
- num = int(num);
- while (num > 0) {
- rem = num % 256;
- hex = raw_string(rem, hex);
- num = num / 256;
- if (num > 0 && num < 255) {
- hex = raw_string(num, hex);
- num = 0;
- }
- }
- if (!hex) hex = raw_string(0x00);
-
- return hex;
- }
-
- # Convert a Date CVS field to Unix time
- # Michel Arboi
-
- function cvsdate2unixtime(date)
- {
- local_var v, u;
- if (! defined_func("mktime")) return NULL; # We could write it in NASL...
- v = eregmatch(string: date, pattern: "\$Date: 2004/12/12 11:38:34 $");
- if (isnull(v)) return;
- u = mktime(year: v[1], mon: v[2], mday: v[3], hour: v[3], min: v[5], sec: v[6]);
- return u;
- }
-
-